package com.allenja.eleviewer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnKeyListener;
import android.text.Editable;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

@SuppressLint("SdCardPath")
public class SelectTerrainModelDirectory {
    private boolean dirChooserIsNewFolderEnabled = false;
    private String sdcardDirectory = "/mnt/sdcard/external_sd/Terrain Models";
    private Context dirChooserContext;
    private TextView titleView;
  
    private String modelDir = "";
    private List<String> modelSubdirs = null;
    private ChosenDirectoryListener dirChooserChosenDirectoryListener = null;
    private ArrayAdapter<String> listAdapter = null;

    public interface ChosenDirectoryListener {
        public void onChosenDir(String chosenDir);
    }

    public SelectTerrainModelDirectory(Context context, ChosenDirectoryListener chosenDirectoryListener) throws IOException {
    	dirChooserContext = context;
        dirChooserChosenDirectoryListener = chosenDirectoryListener;

        sdcardDirectory = new File(sdcardDirectory).getAbsolutePath();
    }

    public void setNewFolderEnabled(boolean isNewFolderEnabled) {
    	dirChooserIsNewFolderEnabled = isNewFolderEnabled;
    }

    public boolean getNewFolderEnabled() {
        return dirChooserIsNewFolderEnabled;
    }

    public void chooseDirectory() {
        // Initial directory is sdcard directory
        try {
			chooseDirectory(sdcardDirectory);
		} 
        catch (IOException e) {
			e.printStackTrace();
		}
    }

    public void chooseDirectory(String dir) throws IOException {
        File dirFile = new File(dir);
        
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            dir = sdcardDirectory;
        }

        dir = new File(dir).getAbsolutePath();

        modelDir = dir;
        modelSubdirs = getDirectories(dir);

    class DirectoryOnClickListener implements DialogInterface.OnClickListener {
    	
        public void onClick(DialogInterface dialog, int item) {
            // Navigate into the sub-directory
            modelDir += "/" + ((AlertDialog) dialog).getListView().getAdapter().getItem(item);
            updateDirectory();
        }
    }

    AlertDialog.Builder dialogBuilder = createDirectoryChooserDialog(dir, modelSubdirs, new DirectoryOnClickListener());

    dialogBuilder.setPositiveButton("OK", new OnClickListener() {
    	
        public void onClick(DialogInterface dialog, int which) {
            // Current directory chosen
            if (dirChooserChosenDirectoryListener != null) {
                // Call registered listener supplied with the chosen directory
                dirChooserChosenDirectoryListener.onChosenDir(modelDir);
            }
        }
    }).setNegativeButton("Cancel", null);

    final AlertDialog dirsDialog = dialogBuilder.create();

    dirsDialog.setOnKeyListener(new OnKeyListener() {
    	
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        	
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
                // Back button pressed
                if ( modelDir.equals(sdcardDirectory)) {
                    // The very top level directory, do nothing
                    return false;
                }
                else {
                    // Navigate back to an upper directory
                    modelDir = new File(modelDir).getParent();
                    updateDirectory();
                }
    
                return true;
            }
            else {
                return false;
            }
        }
    });

    // Show directory chooser dialog
    dirsDialog.show();
	}

	private boolean createSubDir(String newDir) {
	    File newDirFile = new File(newDir);
	    
	    if (!newDirFile.exists()) {
	        return newDirFile.mkdir();
	    }

	    return false;
	}

	private List<String> getDirectories(String dir) {
	    List<String> dirs = new ArrayList<String>();

	    try {
	        File dirFile = new File(dir);
	        if (!dirFile.exists() || !dirFile.isDirectory()) {
	            return dirs;
	        }
	 
	        for (File file : dirFile.listFiles()) {
	            if (file.isDirectory()) {
	                dirs.add(file.getName());
	            }
	        }
	    }
	    catch (Exception e) {
	    }

	    Collections.sort(dirs, new Comparator<String>() {
	    	
	        public int compare(String o1, String o2) {
	            return o1.compareTo(o2);
	        }
	    });

	    return dirs;
	}

	private AlertDialog.Builder createDirectoryChooserDialog(String title, List<String> listItems, DialogInterface.OnClickListener onClickListener)	{
	    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(dirChooserContext);

	    // Create custom view for AlertDialog title containing 
	    // current directory TextView and possible 'New folder' button.
	    // Current directory TextView allows long directory path to be wrapped to multiple lines.
	    LinearLayout titleLayout = new LinearLayout(dirChooserContext);
	    titleLayout.setOrientation(LinearLayout.VERTICAL);

	    titleView = new TextView(dirChooserContext);
	    titleView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
	    titleView.setTextAppearance(dirChooserContext, android.R.style.TextAppearance_Large);
	    titleView.setTextColor( dirChooserContext.getResources().getColor(android.R.color.black));
	    titleView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
	    titleView.setText(title);

	    Button newDirButton = new Button(dirChooserContext);
	    newDirButton.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
	    newDirButton.setText("New folder");
	    
	    newDirButton.setOnClickListener(new View.OnClickListener() {
	    	
	        public void onClick(View v) {
	            final EditText input = new EditText(dirChooserContext);

	            // Show new folder name input dialog
	            new AlertDialog.Builder(dirChooserContext).setTitle("New folder name").setView(input).setPositiveButton("OK", new DialogInterface.OnClickListener() {
	            	
	                public void onClick(DialogInterface dialog, int whichButton) {
	                    Editable newDir = input.getText();
	                    String newDirName = newDir.toString();
	                    // Create new directory
	                    if (createSubDir(modelDir + "/" + newDirName)) {
	                        // Navigate into the new directory
	                        modelDir += "/" + newDirName;
	                        updateDirectory();
	                    }
	                    else {
	                        Toast.makeText(
	                        dirChooserContext, "Failed to create '" + newDirName + "' folder", Toast.LENGTH_SHORT).show();
	                    }
	                }
	            }).setNegativeButton("Cancel", null).show(); 
	        }
	    });

	    if (!dirChooserIsNewFolderEnabled) {
	        newDirButton.setVisibility(View.GONE);
	    }

	    titleLayout.addView(titleView);
	    titleLayout.addView(newDirButton);

	    dialogBuilder.setCustomTitle(titleLayout);

	    listAdapter = createListAdapter(listItems);

	    dialogBuilder.setSingleChoiceItems(listAdapter, -1, onClickListener);
	    dialogBuilder.setCancelable(false);

	    return dialogBuilder;
	}

	private void updateDirectory() {
	    modelSubdirs.clear();
	    modelSubdirs.addAll(getDirectories(modelDir));
	    titleView.setText(modelDir);

	    listAdapter.notifyDataSetChanged();
	}

	private ArrayAdapter<String> createListAdapter(List<String> items) {
	    return new ArrayAdapter<String>(dirChooserContext, android.R.layout.select_dialog_item, android.R.id.text1, items) {
	        @Override
	        public View getView(int position, View convertView, ViewGroup parent) {
	            View v = super.getView(position, convertView, parent);

	            if (v instanceof TextView) {
	                // Enable list item (directory) text wrapping
	                TextView tv = (TextView) v;
	                tv.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
	                tv.setEllipsize(null);
	            }
	            return v;
	        }
	    };
	}
}
